package pe.com.cotelasa.common.servicios;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.mail.MailAuthenticationException;
import org.springframework.mail.MailException;
import org.springframework.mail.MailParseException;
import org.springframework.mail.MailPreparationException;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;

import pe.com.cotelasa.common.excepcion.FailedSendEmailException;
import pe.com.cotelasa.scp.dominio.common.util.UtilitarioCadenas;
import pe.com.cotelasa.scp.dominio.excepcion.ServiceException;

@Service("servicioCorreo")
public class ServicioCorreoImpl implements IServicioCorreo {

	protected static Logger logger = Logger.getLogger(ServicioCorreoImpl.class);
	
	@Autowired
	private EmailMessagePreparator sendEmail;
	
	@Autowired
	@Qualifier("serviceProperties")
	private Properties emailProperties;

	@Autowired
	private JavaMailSenderImpl emailSender;

	
	@Override
	public void enviarCorreoUsuario() throws ServiceException {
		String velocityParam = "";
		String message = "";
		String template = "";
		Map<String, Object> emailparam = new HashMap<String, Object>();
		Map<String, Object> velocityparam = new HashMap<String, Object>();
 		String emailTo = "";
 		velocityparam.put(velocityParam, message);
  		emailparam.put("to", new String[] { emailTo });
		sendEmail(template,emailparam,velocityparam);
	}
	
	@Override
	public void enviarCorreoUsuario(String emailUsuario, String nuevaContracenia)
			throws ServiceException {
		Map<String, Object> emailparam = new HashMap<String, Object>();
		Map<String, Object> velocityparam = new HashMap<String, Object>();
		String template = "correoUsuario";
		String velocityParam = "";
		String message = "";
		velocityparam.put(velocityParam, message);
		emailparam.put("to",new String[]{emailUsuario});
		sendEmail(template, emailparam, velocityparam);
	}
	
	public void sendEmail(String template, Map emailparam, Map velocityparam) throws FailedSendEmailException  {
		sendEmail(template, emailparam, velocityparam, "");
	}

	public void sendEmail(String template, Map emailparam, Map velocityparam, boolean deleteAttach) throws FailedSendEmailException  {
		sendEmail(template, emailparam, velocityparam, "", deleteAttach);
	}

	public void sendEmail(String template, Map emailparam, Map velocityparam, String addSubject) throws FailedSendEmailException  {
		this.sendEmail(template, emailparam, velocityparam, addSubject, true);
	}

	public void sendEmail(String template, Map emailparam, Map velocityparam, String addSubject, boolean deleteAttach) throws FailedSendEmailException  {
		String emailTo[] = (String[])emailparam.get("to");
		if (emailTo==null)
			throw new FailedSendEmailException("error.parameter.email");
		for(String emailString:emailTo)
		{
			emailparam.put("to", emailString.split(";"));
			sendUniqueEmail(template, emailparam, velocityparam, addSubject, deleteAttach);
		}
	}

	/**
	 * This method send email's from the emailparam, but don't send if an email is empty or null
	 * and not thrown expection
	 * @param template
	 * @param potentialCustomers
	 * @param velocityparam
	 * @param addSubject
	 * @param deleteAttach
	 */
	public void sendEmailOptional(String template, Map potentialCustomers, Map<String, Object> velocityparam, String addSubject, boolean deleteAttach) throws FailedSendEmailException  {
		String emailList[] = (String[])potentialCustomers.get("email");
		String nameList[] = (String[])potentialCustomers.get("name");
		Map<String, Object> emailparam = new HashMap<String, Object>();
		
		
		for(int i=0; i<emailList.length; i++) {
			if(emailList[i]!=null && !emailList[i].trim().equals("")) {
				emailparam.put("to", emailList[i].split(";"));
				velocityparam.put("friendName", nameList[i]);
				sendUniqueEmail(template, emailparam, velocityparam, addSubject, deleteAttach);
			}
		}
	}

	public void sendUniqueEmail(String template, Map emailparam, Map velocityparam, String addSubject) throws FailedSendEmailException  {
		this.sendUniqueEmail(template, emailparam, velocityparam, addSubject, true);
	}
	/**
	 * Send an unique email.
	 * @param template 
	 * @param emailparam  Map with this parameters: subject, to, from parameters  
	 * @param velocityparam Map with parameters defined in the template.
	 * @param addSubject Additional subject
	 * @param deleteAttach flag if you want to delete attached file
	 * @throws FailedSendEmailException
	 */
	public void sendUniqueEmail(String template, Map emailparam, Map velocityparam, String addSubject, boolean deleteAttach) throws FailedSendEmailException  {
	    try {

	    	EmailMessagePreparator sendEmail2 = new EmailMessagePreparator();
	    	sendEmail2.setVelocityEngine(sendEmail.getVelocityEngine());
	    	
	    	//from of the template
	    	String from = emailProperties.getProperty(template+".from");
	    	System.out.println("From : " + from);
	    	String fromParam = (String)emailparam.get("from");
	    	System.out.println("fromParam : " + fromParam);
	    	if (UtilitarioCadenas.isEmpty(from) && UtilitarioCadenas.isEmpty(fromParam)){
	    		throw new FailedSendEmailException("error.parameter.template");
	    	}
	    	if(emailparam.size()==0){
	    		throw new FailedSendEmailException("error.parameter.email");
	    	}
	    	if(velocityparam.size()==0){
	    		throw new FailedSendEmailException("error.parameter.velocity");
	    	}
	    	if(emailparam.get("to")==null){
	    		throw new FailedSendEmailException("error.parameter.to.null");
	    	}
	    	
	    	//if from and fromParam have values, from has more priority.
	    	if(!UtilitarioCadenas.isEmpty(from)){
	    		sendEmail2.setFrom(new String[]{from});
	    	}else{
	    		sendEmail2.setFrom(new String[]{fromParam});
	    	}
	    	
	    	sendEmail2.setHtmlTemplate(emailProperties.getProperty(template+".htmlTemplate"));
	    	System.out.println("HtmlTemplate " + sendEmail2.getHtmlTemplate());
	    	sendEmail2.setPlainTextTemplate(emailProperties.getProperty(template+".plainTextTemplate"));
	    	System.out.println("PlainTemplate " + sendEmail2.getPlainTextTemplate());
	    	sendEmail2.setSubject(emailProperties.getProperty(template+".subject"));
	    	System.out.println("Subject " + sendEmail2.getSubject());
	    	if (addSubject!=null) {
	    		if(!"".equals(addSubject)) {
	    			sendEmail2.setSubject( sendEmail2.getSubject() + addSubject);
	    		}
	    	}
//	    	this.sendEmail.setTo(new String[]{(String)emailparam.get("to")});
	    	sendEmail2.setTo((String[]) emailparam.get("to"));
	    	System.out.println("To: "  + sendEmail2.getTo());
	    	 
	    	sendEmail2.setData(velocityparam);
	    	this.emailSender.send(sendEmail2);

	    	 
	    }
	    catch (MailPreparationException mex) {
	    	mex.printStackTrace();
	    	logger.error("error.preparing.message", mex);
	    	throw new FailedSendEmailException("error.preparing.message");
	    }
	    catch(MailParseException mex){
	    	logger.error("error.parse.message", mex);
	    	throw new FailedSendEmailException("error.parse.message");
	    }
	    catch(MailAuthenticationException mex){
	    	logger.error("error.authentication.message", mex);
        	throw new FailedSendEmailException("error.authentication.message");
	    }
	    catch(MailSendException mex){
	    	String message = mex.getMessage();
	    	if (message.contains("Mail server connection failed") || message.contains("timeout exceeded")) {
	    		logger.error("error.send.message.server", mex);
		    	throw new FailedSendEmailException("error.send.message.server");
	    	}
	    	// message.contains("Invalid Addresses")
	    	logger.error("error.send.message", mex);
	    	throw new FailedSendEmailException("error.send.message");
	    }
	    catch(MailException mex){
	    	logger.error("error.mail.exception", mex);
        	throw new FailedSendEmailException("error.mail.exception");
	    }
 
	}


	@Override
	public void enviarCorreoError(String mensajeError, Throwable e)
			throws ServiceException {
	 
	}

}
